package Graphics::PlanarVector::FontPath;
use Graphics::SVG::Path 'SVGpath';
use Graphics::PlanarVector::Path 'path';
use Exporter 'import';
use Font::FreeType;
our @EXPORT_OK = 'load_font';

sub load_font {
	my $ft = Font::FreeType->new;
	my @a = split(';', $_[0]);
	my $face = $ft->face($a[0],
		load_flags=>FT_LOAD_NO_HINTING,
		index=>$a[1] || 0);
	my $size = $a[2] || 100;
	my $dpi = $a[3] || 100;
	$face->set_char_size(($size) x 2, ($dpi) x 2);
	bless { face => $face, name=>$_[0] };
}

sub string_path {
	my ($f, $str) = @_;
	my (@paths, $x, $y);
	for (split '', $str) {
		my $gly = $f->{face}->glyph_from_char($_);
		$x //= $gly->left_bearing;
		$y //= $gly->vertical_advance;

		if (!$gly->has_outline) {
			warn "Char '$_' in font $f->{name} has no outline"
				if $^W;
		} else {
			my $path = path;
			my $draw = sub {
				my @v = splice(@_, 2);
				$path->curveto(@v, @_)
			};
			$gly->outline_decompose(
				move_to	=> sub { $path->moveto(@_) },
				line_to	=> $draw,
				conic_to=> $draw,
				cubic_to=> $draw,
			);

			push @paths, $path->translate($x, 0);
		}
		$x += $gly->horizontal_advance;
	}
	my $p = Graphics::PlanarVector::Path::path_combine(@paths)->scale(1,-1);
	wantarray ? ($p, $x, $y) : $p
}

1;

__END__
=head1 NAME

Graphics::PlanarVector::FontPath - Load font outline as C<Graphics::PlanarVector::Path> object

=head1 SYNOPSIS

    use Graphics::PlanarVector::FontPath 'load_font';
    $font = load_font('/user/share/font/italic.ttf;0;24;72');
    $path = $fnt->string_font('abc');

=head1 DESCRIPTION

=over 4

=item B<load_font> FONT_SPEC

This function may be imported.  Returns a fontface object from which glyph
paths can be loaded.  FONT_SPEC is a semi-colon separated list:

    filename;face_index;font_size;dpi

whereas:

=over 4

=item I<filename>

The pathname to the font file.

=item I<face_index>

The index of desired font face if the font file contains more than one faces; default to the first (0).

=item I<font_size>

Defaults to 100.

=item I<dpi>

Resolution (dots per inch).  Defaults to 100.

=back

=item B<string_path> STRING

    ($path, $horizontal_advance, $vertical_advance) =
            $font->string_path('abc');

Method of a fontface object.  Under scalar context it returns a
C<Graphics::PlanarVector::Path> object; under list context it also returns
the accumulated glyph advances of STRING, so multiple char paths can be
assembled and adjusted.  Point (0,0) in the returned path is the begining of
the character baseline.

=back

=cut
